home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue29 / construc / INDEX.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1997-11-27  |  5.6 KB  |  233 lines

  1. unit Index;
  2. {$I-}
  3. interface
  4. const
  5.   website = 'http://www.drbob42.com';
  6.  
  7. const
  8.   IdentSet = ['A'..'Z','a'..'z','0'..'9','-','+'];
  9.   StartSet = ['A'..'Z','a'..'z'];
  10.  
  11. const
  12.   MaxPage = 255;
  13.  
  14. type
  15.   TNumPage = 0..MaxPage; { max number of webpages in site }
  16.   TURLPage = ShortString { assuming URL <= 255 characters };
  17.  
  18. var
  19.   WebPages: TNumPage = 0;
  20.   WebPage: Array[TNumPage] of TURLPage;
  21.  
  22. const
  23.   MaxKeyword = 31;
  24.  
  25. type
  26.   TKeyword = String[MaxKeyword];
  27.   TPageSet = Set of TNumPage;
  28.  
  29. type
  30.   TNode = record
  31.     Keyword: TKeyword; { 32 bytes }
  32.     URLs: TPageSet;    { 32 bytes }
  33.   end {TNode};
  34.  
  35.   TTree = class
  36.     Node: TNode;
  37.     constructor Create(const Keyword: TKeyword; WebPage: TNumPage);
  38.     destructor Destroy; override;
  39.   private
  40.     Prev,Next: TTree;
  41.   end {TTree};
  42.  
  43. var
  44.   Keywords: Integer = 0;
  45.   root: TTree = nil;
  46.  
  47. type
  48.   TIndexFile = File of TNode;
  49.  
  50. implementation
  51. uses
  52.   SysUtils;
  53.  
  54.   constructor TTree.Create(const Keyword: TKeyword; WebPage: TNumPage);
  55.   begin
  56.     inherited Create;
  57.     Inc(Keywords); // keep track of number of keywords
  58.     Prev := nil;
  59.     Next := nil;
  60.     Node.Keyword := Keyword;
  61.     Node.URLs := [WebPage]
  62.   end {Create};
  63.  
  64.   destructor TTree.Destroy;
  65.   begin
  66.     if Prev <> nil then Prev.Free;
  67.     if Next <> nil then Next.Free;
  68.     inherited Destroy
  69.   end {Destroy};
  70.  
  71.   procedure AddKeyword(const Keyword: TKeyword; WebPage: TNumPage);
  72.   var
  73.     tmp: TTree;
  74.   begin
  75.     if root = nil then
  76.       root := TTree.Create(Keyword,WebPage)
  77.     else { search }
  78.     begin
  79.       tmp := root;
  80.       repeat
  81.         if tmp.Node.Keyword > Keyword then
  82.         begin
  83.           if tmp.Prev = nil then
  84.             tmp.Prev := TTree.Create(Keyword,WebPage);
  85.           tmp := tmp.Prev
  86.         end
  87.         else
  88.           if tmp.Node.Keyword < Keyword then
  89.           begin
  90.             if tmp.Next = nil then
  91.               tmp.Next := TTree.Create(Keyword,WebPage);
  92.             tmp := tmp.Next
  93.           end
  94.       until tmp.Node.Keyword = Keyword;
  95.       tmp.Node.URLs := tmp.Node.URLs + [WebPage]
  96.     end
  97.   end {AddKeyword};
  98.  
  99.   procedure ScanPage(const FileName: ShortString; WebPage: TNumPage);
  100.   var
  101.     f: Text;
  102.     NotInTag: Boolean;
  103.     Keyword: ShortString;
  104.     Len: Byte absolute Keyword;
  105.   begin
  106.     assign(f,FileName);
  107.     reset(f);
  108.     if IOResult = 0 then
  109.     begin
  110.       writeln('<LI><B>',FileName,'</B>');
  111.       NotInTag := True;
  112.       while not eof(f) do
  113.       begin
  114.         Len := 0;
  115.         while not eoln(f) do
  116.         begin
  117.           Inc(Len);
  118.           read(f,Keyword[Len]);
  119.           if not (Keyword[Len] in IdentSet) then
  120.           begin
  121.             Dec(Len);
  122.             if (Len > 2) and NotInTag then
  123.               AddKeyword(LowerCase(Keyword),WebPage);
  124.             if Keyword[Len+1] = '>' then NotInTag := True
  125.             else
  126.               if Keyword[Len+1] = '<' then NotInTag := False;
  127.             Len := 0
  128.           end
  129.           else
  130.             if (Len = 1) then { start with letter ?? }
  131.               if not (Keyword[1] in StartSet) then Len := 0
  132.         end;
  133.         if (Len > 2) and NotInTag then
  134.           AddKeyword(LowerCase(Keyword),WebPage);
  135.         readln(f)
  136.       end;
  137.       close(f)
  138.     end
  139.     else
  140.       writeln('<LI>',FileName); { failed to open }
  141.   end {ScanPage};
  142.  
  143.   procedure ScanPages(const Path: ShortString);
  144.   var
  145.     SRec: TSearchRec;
  146.   begin
  147.     if FindFirst('*.*', faDirectory, SRec) = 0 then
  148.     repeat
  149.       if (SRec.Attr AND faDirectory) = faDirectory then
  150.       begin
  151.         if (SRec.Name[1] <> '.') then { skip '.' and '..' }
  152.         if Pos('_vti',SRec.Name) = 0 then { _vti_cnf etc. }
  153.         begin
  154.           ChDir(SRec.Name);
  155.           if IOResult = 0 then
  156.           begin
  157.             writeln('<LI><I>',SRec.Name,'</I>');
  158.             writeln('<UL>');
  159.             ScanPages(Path+'/'+SRec.Name); { recursive!! }
  160.             writeln('</UL>');
  161.             ChDir('..')
  162.           end
  163.           else
  164.             writeln('<LI><I>',SRec.Name,'</I> - locked')
  165.         end
  166.       end
  167.       else { file }
  168.       if (Pos('.HTM',UpperCase(SRec.Name)) > 0) or
  169.          (Pos('.ASP',UpperCase(SRec.Name)) > 0) then
  170.       begin
  171.         WebPage[WebPages] := Path + '/' + SRec.Name;
  172.         ScanPage(SRec.Name,WebPages);
  173.         Inc(WebPages)
  174.       end
  175.     until FindNext(SRec) <> 0;
  176.     FindClose(SRec)
  177.   end {ScanPages};
  178.  
  179.   procedure WriteTree(var IndexFile: TIndexFile; root: TTree);
  180.   begin
  181.     if root.Prev <> nil then WriteTree(IndexFile,root.Prev);
  182.     write(IndexFile,root.Node);
  183.     if root.Next <> nil then WriteTree(IndexFile,root.Next);
  184.   end {WriteTree};
  185.  
  186. var
  187.   i: Integer;
  188.   PageFile: Text;
  189.   IndexFile: TIndexFile;
  190.  
  191. initialization
  192.   ChDir('..');
  193.   if IOResult <> 0 then { skip };
  194.   writeln('content-type: text/html');
  195.   writeln;
  196.   writeln('<HTML>');
  197.   writeln('<BODY BACKGROUND="/gif/back.gif">');
  198.   writeln('<H2>IndexBob</H2>');
  199.   writeln('Creating index for: ',website);
  200.   writeln('<P>');
  201.   writeln('<UL>');
  202.   ScanPages(website);
  203.   writeln('</UL>');
  204.   ChDir('cgi-bin');
  205.   if IOResult <> 0 then { skip };
  206.   assign(PageFile,'pages.bob');
  207.   try
  208.     rewrite(PageFile);
  209.     for i:=0 to WebPages-1 do
  210.       writeln(PageFile,WebPage[i]);
  211.   finally
  212.     close(PageFile)
  213.   end;
  214.   assign(IndexFile,'index.bob');
  215.   if root <> nil then
  216.   try
  217.     rewrite(IndexFile);
  218.     WriteTree(IndexFile,root)
  219.   finally
  220.     close(IndexFile)
  221.   end;
  222.   writeln('<HR>');
  223.   writeln('<FONT SIZE=1>');
  224.   writeln('Webpages: ',WebPages);
  225.   writeln('<BR>Keywords: ',Keywords);
  226.   writeln('</FONT>');
  227.   writeln('<HR>');
  228.   writeln('</BODY>');
  229.   writeln('</HTML>')
  230. finalization
  231.   root.Free
  232. end.
  233.